package com.hzqy.commons.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Properties;

public class WChatUtils {
    private static final Log LOG = LogFactory.getLog(WChatUtils.class);
    private static String proPath = "wchatConfig.properties";
    private static String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";//获取access_token地址
    private static String QR_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create";//二维码获取地址
    private static String TICKET_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode";//ticket换取二维码图片地址
    private static String TOKEN_WEB = "https://api.weixin.qq.com/sns/oauth2/access_token";//网页授权获取TOKEN
    private static String MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create";//菜单创建地址
    private static String MENU_URL_DEL = "https://api.weixin.qq.com/cgi-bin/menu/delete";//菜单创建地址
    private static String USER_INFO = "https://api.weixin.qq.com/cgi-bin/user/info";//获取用户基本信息接口
    private static HashMap<String,String> wchatConfigHash = new HashMap<>();

    private WChatUtils(){}

    /**
     * 获取微信access_token
     * @return
     */
    public static String getAccessToken(){
        wchatConfigHash = getWchatParams();
        String accessUrl = TOKEN_URL+"?grant_type=client_credential&appid="+wchatConfigHash.get("APPID")+"&secret="+wchatConfigHash.get("secret");
        return sendPost(accessUrl,null);
    }

    /**
     * 获取微信网页授权access_token
     * @return
     */
    public static String getWebAccessToken(String code){
        wchatConfigHash = getWchatParams();
        String accessUrl = TOKEN_WEB+"?grant_type=authorization_code&appid="+wchatConfigHash.get("APPID")+"&secret="+wchatConfigHash.get("secret")+"&code="+code;
        return sendGet(accessUrl);
    }

    /**
     * 创建二维码ticket
     * @param accessToken
     * @param QRTime
     * @param serverId
     * @return
     * @throws IOException
     */
    public static String getQRSCENE(String accessToken, int QRTime, String serverId) throws IOException {
        String QRUrl = QR_URL+"?access_token="+accessToken;
        String jsonmsg = "{\"expire_seconds\":"+QRTime+",\"action_name\": \"QR_STR_SCENE\",\"action_info\":{\"scene\":{\"scene_str\":\"serverID:"+serverId+"\"}}}";
        return sendPost(QRUrl,jsonmsg);
    }

    /**
     * 创建菜单栏
     */
    public static String createButton(String accessToken, String jsonStr) throws IOException {
        String buttonUrl = MENU_URL+"?access_token="+accessToken;
        return sendPost(buttonUrl,jsonStr);
    }

    public static String delButton(String accessToken) {
        String buttonUrl = MENU_URL_DEL+"?access_token="+accessToken;
        return sendPost(buttonUrl,"");
    }

    /**
     * 获取带参数二维码图片流
     * @param ticket
     * @return
     * @throws IOException
     */
    public static String getQRPIC(String ticket) throws IOException {
        String QRTicketUrl = TICKET_URL+"?ticket="+ URLEncoder.encode(ticket,"UTF-8");
        return getQRCodeInputStream(QRTicketUrl);
    }

    /**
     * 获取域名
     * @return
     */
    public static String getDomain(){
        wchatConfigHash = getWchatParams();
        return wchatConfigHash.get("domain");
    }
    /**
     * 获取APPID
     * @return
     */
    public static String getAPPID(){
        wchatConfigHash = getWchatParams();
        return wchatConfigHash.get("APPID");
    }

    /**
     * 获取用户基本信息
     * @return
     */
    public static String getUserInfoFromBasisToken(String accessToken, String openid){
        wchatConfigHash = getWchatParams();
        String accessUrl = USER_INFO+"?access_token="+accessToken+"&openid="+openid+"&lang=zh_CN";
        return sendGet(accessUrl);
    }

    public static String sendPost(String urlStr, String outputStr) {
        HttpURLConnection con = null;
        OutputStream outputStream = null;
        String result = "";
        if(!UrlUtil.URL_LIST.contains(urlStr)) {
            try {
                URL url = new URL(urlStr);
                con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("POST");
                con.setConnectTimeout(1000);
                con.setReadTimeout(5000);
                con.setDoOutput(true);
                con.setDoInput(true);
                con.setRequestProperty("version", "1.0");
                con.setRequestProperty("Content-Type", "text/xml");
                con.setRequestProperty("Pragma", "no-cache");
                con.setRequestProperty("Cache-Control", "no-cache");

                if (null != outputStr) {
                    outputStream = con.getOutputStream();
                    outputStream.write(outputStr.getBytes("UTF-8"));
                    outputStream.close();
                }

                result = getConnectionData(con);
            } catch (Exception e) {
                e.printStackTrace();
                LOG.error("请求失败", e);
            } finally {
                if (con != null)
                    con.disconnect();
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                    }
                }
            }
        }

        return result;
    }

    public static String sendGet(String urlStr) {
        HttpURLConnection con = null;
        String result = "";
        if(!UrlUtil.URL_LIST.contains(urlStr)) {
            try {
                URL url = new URL(urlStr);
                con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("GET");
                con.setConnectTimeout(1000);
                con.setReadTimeout(5000);
                con.connect();
                result = getConnectionData(con);
            } catch (Exception e) {
                e.printStackTrace();
                LOG.error("请求失败", e);
            } finally {
                if (con != null)
                    con.disconnect();
            }
        }
        return result;
    }

    public static String getQRCodeInputStream(String QRURL){
        InputStream inputStream = null;
        if(!UrlUtil.URL_LIST.contains(QRURL)) {
            try {
                URL url = new URL(QRURL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setConnectTimeout(3000);
                httpConn.setDoInput(true);
                httpConn.setRequestMethod("GET");
                if (httpConn.getResponseCode() == 200) {
                    inputStream = httpConn.getInputStream();
                    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                    byte[] by = new byte[1024];
                    int len = -1;
                    while ((len = inputStream.read(by)) != -1) {
                        byteStream.write(by, 0, len);
                    }
                    inputStream.close();
                    BASE64Encoder encoder = new sun.misc.BASE64Encoder();
                    return encoder.encode(byteStream.toByteArray());
                }
            } catch (IOException e) {
                LOG.error("二维码图片流获取失败：", e);
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        return null;
    }

    private static String getConnectionData(HttpURLConnection con){
        String result = "";
        try {
            if (con.getResponseCode() == 200) {
                BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
                for (String line = br.readLine(); line != null; line = br.readLine()) {
                    result += line;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    private static HashMap<String, String> getWchatParams(){
        InputStream inStream=null;
        try {
            if(wchatConfigHash.size() <= 0){
                Properties props = new Properties();
                inStream = WChatUtils.class.getClassLoader().getResourceAsStream(proPath);
                props.load(inStream);
                // props.load(WChatUtils.class.getClassLoader().getResourceAsStream(proPath));
                wchatConfigHash.put("token",String.valueOf(props.getProperty("wchat.token")));
                wchatConfigHash.put("APPID",String.valueOf(props.getProperty("wchat.appid")));
                wchatConfigHash.put("secret",String.valueOf(props.getProperty("wchat.secret")));
                wchatConfigHash.put("signup",String.valueOf(props.getProperty("wchat.signup")));
                wchatConfigHash.put("domain",String.valueOf(props.getProperty("wchat.domain")));
            }
        } catch (IOException e){
            LOG.error("微信服务号配置信息读取失败 :", e);
        }finally {
            if(inStream!=null){
                try {
                    inStream.close();
                } catch (IOException e) {
                    LOG.debug("getWchatParams输入流释放异常："+e);
                }
            }
        }
        return wchatConfigHash;
    }
}